package cn.xyh.shiro;


import cn.xyh.exception.RoleException;
import cn.xyh.model.User;
import cn.xyh.service.IRoleService;
import cn.xyh.util.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 * @author zhumin
 * @ClassName: ShiroDbRealm
 * @Description: shiro权限中心
 * @date 2016年8月1日 上午10:37:47
 */
public class UserRealm extends AuthorizingRealm {

    private static Logger LOGGER = LoggerFactory.getLogger(UserRealm.class);

    @Autowired
    private IRoleService roleService;

    /**
     * 认证回调函数, 登录时调用
     * Shiro登录认证(原理：用户提交 用户名和密码  --- shiro 封装令牌 ---- realm 通过用户名将密码查询返回 ---- shiro 自动去比较查询出密码和用户输入密码是否一致---- 进行登陆控制 )
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken authcToken) throws AuthenticationException {
        LOGGER.info("Shiro开始登录认证");
        UsernamePasswordToken token = null;
        User shiroUser = null;
        try {
            token = (UsernamePasswordToken) authcToken;
            String username = (String) token.getPrincipal();
            List<Long> roleList = roleService.getRoleListById(username);
            shiroUser = new User(token.getUsername(), roleList);
        } catch (RoleException e) {
            e.printStackTrace();
        }
        // 认证缓存信息
        return new SimpleAuthenticationInfo(shiroUser, token.getPassword(), getName());

    }

    /**
     * Shiro权限认证
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {

        Set<String> urlSet = null;
        try {
            User shiroUser = (User) principals.getPrimaryPrincipal();
            List<Long> roleList = shiroUser.roleList;
            urlSet = new HashSet<String>();
            for (Long roleId : roleList) {
                List<Map<Long, String>> roleResourceList = roleService.findRolePermissionListByRoleId(roleId);
                if (roleResourceList != null) {
                    for (Map<Long, String> map : roleResourceList) {
                        if (StringUtils.isNotBlank(map.get("url_path"))) {
                            urlSet.add(map.get("url_path"));
                        }
                    }
                }
            }
        } catch (RoleException e) {
            e.printStackTrace();
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(urlSet);
        return info;
    }
}
